/*
 * WLConnectionManager.java
 *
 * Copyright (c) 2002 Syrrx, Inc.
 * 10410 Science Center Drive, San Diego, CA 92121
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of Syrrx, Inc.
 * ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the
 * license agreement you entered into with Syrrx.
 *
 */

package com.ctepl.common.db;

import javax.naming.*;
import javax.rmi.*;
import java.sql.*;
import javax.sql.*;
import java.util.*;
import com.ctepl.common.exception.CteplException;
import org.apache.log4j.Logger;

/**
 * A WLConnectionManager Singleton that abstracts all the JNDI usage and hides the
 * complexities of initial context creation
 * <p>
 * A Service for the database connection for Webapps is defined here and can be
 * obtained by calling the method: <code>getConnection(serviceDesc)</code>
 */
public class WLConnectionManager {

    /** The Singletons private instance **/
    private static final WLConnectionManager _instance = new WLConnectionManager();

    /** The datasource for the current instance **/
    private static String _currDataSource = null;
    
    private static String _chemDataSource = null;

    /** The properties to use on the InitialContext call, null indicates use default getContext() call **/
    private static Properties _namingProperties = null;

    /** The intial context factory class used under WebLogic **/
    private static final String WL_CONTEXT_FACTORY = "weblogic.jndi.WLInitialContextFactory";

	protected static Logger log = Logger.getLogger(WLConnectionManager.class);
	
    /**
     * Default Constructor not publically allowed, this is a Singleton class.
     */
    private WLConnectionManager() {
    }

    /**
     * Gets the WLConnectionManager Singleton instance.
     *
     * @return  The Singleton instance of WLConnectionManager
     */
    static public WLConnectionManager getInstance() {
        return _instance;
    }

    /**
     * Gets the WLConnectionManager Singleton instance.
     *
     * @param The DataSource name
     * @return  The Singleton instance of WLConnectionManager
     */
    static public WLConnectionManager getInstance(String dataSource) {
    	_instance.setCurrDataSource(dataSource);
        return _instance;
    }
    
    static public WLConnectionManager getChemInstance(String dataSource){
    	_instance.set_chemDataSource(dataSource);
    	return _instance;
    }

    /**
     * Sets the InitialContext naming properties for this instance.  Call this
     * once before using the <code>WLConnectionManager.getInstance()</code> call and these properties
     * will be used instead of the default properties on all <code>getHome()</code> calls.
     * <p>
     * Typically the namingProps  Context.INITIAL_CONTEXT_FACTORY and Context.PROVIDER_URL
     * are set for clients not runnning in the WebLogic server vm (such as applets using the
     * WLConnectionManager class).  The applet needs to specify these properties externally as
     * a vm parameter or jndi.property file.
     * <p>
     * Example usage for an applet:
     * <br>
     * <code>
     *  Properties props = WLConnectionManager.getInstance().
     *      createNamingProperties("weblogic.jndi.WLInitialContextFactory","t3://somehost:port");
     *      WLConnectionManager.setNamingProperties(props);
     * </code>
     *
     * @param   namingProperties If not null Properties for setting the naming intial context are set here.
     *          Properties such as the provider url for the host machine.
     */
    static public void setNamingProperties(Properties namingProperties) {
        _namingProperties = namingProperties;
    }

    /**
     * Sets the InitialContext naming properties for this instance.  Call this
     * once before using the <code>WLConnectionManager.getInstance()</code> call and these properties
     * will be used instead of the default properties on all <code>getHome()</code> calls.
     * <p>
     * Typically the namingProps  Context.INITIAL_CONTEXT_FACTORY and Context.PROVIDER_URL
     * are set for clients not runnning in the WebLogic server vm (such as applets using the
     * WLConnectionManager class).  The applet needs to specifiy these properties externally as
     * a vm parameter or jndi.property file.
     * <p>
     * Example usage for an applet:
     * <br>
     * <code>
     *      WLConnectionManager.setNamingProperties("t3://somehost:port");
     * </code>
     *
     * @param providerURL specifies the provider url for the intial context (e.g. "t3://somehost:port")
     */
    static public void setNamingProperties(String providerURL) {
        Properties props = getInstance().createNamingProperties(WL_CONTEXT_FACTORY, providerURL);
        setNamingProperties(props);
    }

    /**
     * Gets the common name of the database DataSource used for this application.
     */
    public String getCurrDataSource() {
        return _currDataSource;
    }

    /**
     * Gets the common name of the database DataSource used for this application.
     */
    private void setCurrDataSource(String dataSource) {
        _currDataSource = dataSource;
    }

    /**
     * A helper to make it easy on a client to set the intial context factory properties
     * that are passed in on getHome().
     * <p>
     * Can be replace by setting vm params or a creating a
     * jndi.properties file (see getHome() call).  This is used to explictly set the
     * environment for getting the naming intial context.  This additonal info is needed when
     * the client calling from a remote host that is not collocated with the ejb app server.
     *
     * @param initialContextFactory the class name for the intial context factory (e.g. "weblogic.jndi.WLInitialContextFactory")
     * @param providerURL specifies the provider url for the intial context (e.g. "t3://somehost:port")
     * @return Properties created from the params and ready for the <code>setNamingProperties()</code> call
     */
    public Properties createNamingProperties(String initialContextFactory, String providerURL) {
        Properties props = new Properties();
        props.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
        props.put(Context.PROVIDER_URL, providerURL);
        return props;
    }


    /**
     * Gets a connection for this applications data source used globally for
     * this application.
     *
     * @return A JDBC Connection object for the RacerX database, or null if exception
     * @throws CteplException if the data source for the connection can not be located
     */
    public static Connection getConnection() throws CteplException {
        Connection conn = null;
        try {        	

            InitialContext initial = null;
            // If user set some properties...use them, otherwise use the default
            if (_namingProperties == null) {
                initial = new InitialContext();
            } else {
                initial = new InitialContext(_namingProperties);
            }

            // Look up the data source by jndi name and get a connection to the data source
            DataSource dataSrc = (DataSource)initial.lookup(_currDataSource);
    //        boolean till=true;
            conn = dataSrc.getConnection();
    //        while (till==true) {
    //            conn = dataSrc.getConnection();
    //            till=conn.isClosed();
    //        }
        } catch (Exception ex) {
            throw new CteplException("WLConnectionManager getConnection() failed for datasource: " + _currDataSource, ex);
        }
        return conn;
    }
    
    /**
     * @author - rahul
     * @date - Feb 6, 2007
     * @return Connection that is specifically for Chemistry database
     * @throws CteplException
     */
    public static Connection getChemConnection() throws CteplException{
    	Connection conn = null;
        try {

            InitialContext initial = null;
            // If user set some properties...use them, otherwise use the default
            if (_namingProperties == null) {
                initial = new InitialContext();
            } else {
                initial = new InitialContext(_namingProperties);
            }

            // Look up the data source by jndi name and get a connection to the data source
            DataSource dataSrc = (DataSource)initial.lookup(_chemDataSource);
            boolean till=true;
            conn = dataSrc.getConnection();
    //        while (till==true) {
    //            conn = dataSrc.getConnection();
    //            till=conn.isClosed();
    //        }
            } catch (Exception ex) {
            throw new CteplException("WLConnectionManager getConnection() failed for datasource: " + _currDataSource, ex);
        }
        return conn;
    }
    

    /*
     * Example usage of this class:
     */
    public static void main( String[] args ) {
    }

	public static void set_chemDataSource(String dataSource) {
		_chemDataSource = dataSource;
	}
}